added Feb 2001 SDK
[windows-sources.git] / shared source / wpf / src / host / shimimpl / main.cxx
blob9403346309981ac6dd0d67de44f3d9cb6aa9ac51
1 //+-----------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // Description:
6 // Implements the main entry point of the PresentationShim used for hosting
7 // Windows Client Applications in the browser
8 //
9 // History:
10 // 2002/06/12-murrayw
11 // Created
12 // 2003/06/03-kusumav
13 // Ported to WCP
14 // 2007/09/20-[....]
15 // Ported Windows->DevDiv. See SourcesHistory.txt.
16 // 2009/08/xx-[....],[....]
17 // PresentationHost 'super-shim' refactoring. Defined ProcessCommandLine and renamed
18 // WinMain->DelegatedWinMain. Compiling the 'shim implementation' code into PHDLL.
19 // See overview in DLL\PresentationHostDll.nativeproj.
21 //------------------------------------------------------------------------
23 #include "Precompiled.hxx"
24 #include "Main.hxx"
25 #include "LoRights.hxx"
26 #include "HostShim.hxx"
27 #include "ClassFactory.hxx"
28 #include "Version.hxx"
29 #include "WatsonReporting.hxx"
30 #include "ShimUtilities.hxx"
31 #include "..\inc\registry.hxx"
33 #define EVENT_SIZE 64
34 #define NO_HOST_TIMEOUT_SECONDS (10 * 60)
36 //******************************************************************************
38 // global variables
40 //******************************************************************************
42 //CComModule _Module; - now using the one defined in DllMain.cxx
43 long g_ServerRefCount;
44 int g_exitCode = 0;
45 DWORD g_dwCommandLineFlags;
46 LPWSTR g_pswzDebugSecurityZoneURL;
47 HANDLE g_hNoHostTimer_shim;
50 //******************************************************************************
52 // DelegatedWinMain - invoked by PresentationHost.exe (shim)
54 //******************************************************************************
56 int PASCAL DelegatedWinMain(__in HINSTANCE hInstance,
57 __in_opt HINSTANCE hPrevInstance,
58 __in_opt LPSTR lpCommandLine,
59 __in int nCmdShow)
61 HRESULT hr = S_OK;
63 // The heap setting and DEPPolicy are not set here since these are setup by PH.EXE shim.
64 // Thus, we have nothing to do here in that respect.
66 EventRegisterMicrosoft_Windows_WPF();
67 EventWriteWpfHostUm_WinMainStart();
69 BOOL bCoInitialized = FALSE;
71 WCHAR wzFileName[PATH_BUFFER_SIZE + 1];
72 WCHAR wzEventName[EVENT_SIZE + 1];
73 WCHAR wzDebugSecurityZoneURL[DEBUGSECURITYZONEURL_BUFFER_SIZE + 1];
74 WCHAR wzDotApplicationURL[INTERNET_MAX_URL_LENGTH];
76 PLUID_AND_ATTRIBUTES pDisabledPrivileges = NULL;
77 DWORD dwDisabledPrivilegesCount = 0;
79 g_dwCommandLineFlags = FLAGS_NONE;
81 // Check for the command line flags
82 CKHR(ParseCommandLine(&g_dwCommandLineFlags, wzFileName, PATH_BUFFER_SIZE, wzEventName, EVENT_SIZE, wzDebugSecurityZoneURL, DEBUGSECURITYZONEURL_BUFFER_SIZE, wzDotApplicationURL, INTERNET_MAX_URL_LENGTH));
84 // Overloading PresentationHost.exe to assist in launching .application files
85 if (*wzDotApplicationURL && (g_dwCommandLineFlags & FLAG_LAUNCHDOTAPPLICATION))
87 CKHR(CoInitialize(NULL));
88 bCoInitialized = TRUE;
89 LaunchClickOnceApplication(wzDotApplicationURL);
90 goto Cleanup;
93 // For the shell open scenario, invoke the browser and exit
94 if (*wzFileName && (FLAGS_NONE == g_dwCommandLineFlags))
96 CKHR(InvokeBrowser(wzFileName));
97 g_exitCode = ERROR_SUCCESS;
98 goto Cleanup;
100 if(*wzDebugSecurityZoneURL && (g_dwCommandLineFlags & FLAG_DEBUGSECURITYZONEURL))
102 g_pswzDebugSecurityZoneURL = wzDebugSecurityZoneURL;
105 // The code below checks to see if the process is running with admin privileges.
106 // If so, it will start a new instance of the process with the same arguments but
107 // with reduced privileges. We don't do this in case a debugger is attached or if
108 // we detect the process was created with a high integrity level (or above) by
109 // running IE elevated as a way to achieve full-trust operation.
110 BOOL isEmbedding = (g_dwCommandLineFlags & FLAG_EMBEDDING);
111 BOOL isDebug = (g_dwCommandLineFlags & FLAG_DEBUG) || IsDebuggerPresent();
113 if (isEmbedding && !isDebug && !IsPresentationHostHighIntegrity())
115 if (ERROR_SUCCESS != GetDisabledPrivileges(&pDisabledPrivileges, &dwDisabledPrivilegesCount))
117 g_exitCode = ERROR_COULD_NOT_LAUNCH_RESTRICTED;
118 goto Cleanup;
121 Assert(dwDisabledPrivilegesCount != 0);
122 Assert(pDisabledPrivileges != NULL);
124 if (!IsCurrentProcessRestricted(pDisabledPrivileges, dwDisabledPrivilegesCount)) // checks ShouldProcessBeRestricted
126 if (!LaunchRestrictedProcess(NULL, pDisabledPrivileges, dwDisabledPrivilegesCount))
128 ReportActivationFaultAndTerminate(WPFHostError2HResult(ERROR_COULD_NOT_LAUNCH_RESTRICTED));
130 g_exitCode = ERROR_SUCCESS;
131 goto Cleanup;
134 // If we aren't exiting then we should clean up
135 if (pDisabledPrivileges != NULL)
137 delete [] pDisabledPrivileges;
138 pDisabledPrivileges = NULL;
142 (void)CheckRegistryAccess();
143 (void)CheckAppDataFolderAccess();
144 // The HRESULT is ignored. If the process exits at this point, IE will fall back on shell activation,
145 // which will lead to infinite relaunching... So, if the registry or file ACL prolem is detected,
146 // we send the Watson report and let ClickOnce deployment fail, which usually leads to the error page.
148 // Set up termination thread if we don't connect to the host
149 if (!isDebug)
151 g_exitCode = ERROR_NO_HOST_INIT_FAILED;
152 DWORD dwTimeoutSeconds = 0;
153 CKHR(GetRegistryDWORD(HKEY_LOCAL_MACHINE, RegKey_WPF_Hosting, RegValue_NoHostTimeoutSeconds, dwTimeoutSeconds, NO_HOST_TIMEOUT_SECONDS));
154 g_hNoHostTimer_shim = TerminateIfNoHost(dwTimeoutSeconds);
155 CHECK_BOOL_FROM_WIN32(g_hNoHostTimer_shim);
156 g_exitCode = 0;
159 CKHR(CoInitialize(NULL));
160 bCoInitialized = TRUE;
162 if (!(g_dwCommandLineFlags & FLAG_EMBEDDING))
164 // Nothing to do
165 g_exitCode = ERROR_NO_COMMAND_SPECIFIED;
166 goto Cleanup;
169 CKHR(CClassFactory::RegisterClassObjects());
171 // Signal the event if one was specified
172 if (g_dwCommandLineFlags & FLAG_EVENT)
174 HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, wzEventName);
175 BOOL success = hEvent != NULL && SetEvent(hEvent);
176 if (hEvent)
178 CloseHandle(hEvent);
181 if (!success)
183 g_exitCode = ERROR_NO_EVENT;
184 goto Cleanup;
188 // For the VS debug scenario, invoke the browser
189 if (*wzFileName && (g_dwCommandLineFlags & FLAG_DEBUG))
191 CKHR(InvokeBrowser(wzFileName));
194 EventWriteWpfHostUm_EnteringMessageLoop();
196 //The message loop will only exit when the main object gets destroyed.
197 MSG msg;
198 while(GetMessage(&msg, NULL, 0, 0))
200 // Forward all messages; ForwardTranslateAccelerator is responsible for determining
201 // which messages are relevant to it.
202 CVersion* pVersion = CHostShim::GetValidVersion();
203 if (pVersion && pVersion->IsAttached() && (pVersion->ForwardTranslateAccelerator(&msg) == NOERROR))
205 continue;
208 TranslateMessage(&msg);
209 DispatchMessage(&msg);
212 Cleanup:
213 CClassFactory::RevokeAllClassObjects();
215 if (pDisabledPrivileges != NULL)
217 delete [] pDisabledPrivileges;
218 pDisabledPrivileges = NULL;
221 if (bCoInitialized)
224 CoEEShutDownCOM() is called to cleanly release RCWs (COM Runtime Callable Wrappers).
225 AppVerifier finds that "A COM Proxy was called from the wrong context". This presumably happens
226 because the Finalizer thread fails to switch to the object's right context and calls
227 IUnknown->Release() directly. See WOSB 1795776.
229 [....] says, "You should also call GetModuleHandle() on mscorwks.dll just to see if it is loaded. [...]
230 CoEEShutdownCOM will cause mscorwks.dll to be loaded even if no managed code has been run."
232 This patch may not be needed once PresentationHost is migrated to the DevDiv depot and starts
233 using the MSVCRT version matching the compiler.
235 if ((GetModuleHandle(L"clr.dll") != NULL) || (GetModuleHandle(L"mscorwks.dll") != NULL))
237 LegacyActivationShim::CoEEShutDownCOM();
240 CoUninitialize();
243 // The only cases above where hr is set to failure code is while starting the app
244 // and if registration failed. If we successfully started the app, return 0
245 int retCode = FAILED(hr) ? hr : g_exitCode;
247 EventWriteWpfHostUm_WinMainEnd((DWORD)retCode);
249 return retCode;
252 // This is the export which is invoked by the shim implementation of
253 // PresentationHost.exe to call into the actual v4+ PresentationHost
254 // implementation.
255 extern "C" int __stdcall ProcessCommandLine(__in HINSTANCE hInstance,
256 __in_opt LPSTR lpCommandLine,
257 __in int nCmdShow)
259 return DelegatedWinMain(hInstance, NULL, lpCommandLine, nCmdShow);